﻿using System;
using UnityEngine;
using UnityEngine.Rendering;

namespace UnityStandardAssets.CinematicEffects
{
	// Token: 0x0200045A RID: 1114
	[ExecuteInEditMode]
	[RequireComponent(typeof(Camera))]
	[AddComponentMenu("Image Effects/Cinematic/Ambient Occlusion")]
	[ImageEffectAllowedInSceneView]
	public class AmbientOcclusion : MonoBehaviour
	{
		// Token: 0x170001CA RID: 458
		// (get) Token: 0x060017BC RID: 6076 RVA: 0x00064D6F File Offset: 0x0006316F
		public bool isAmbientOnlySupported
		{
			get
			{
				return this.targetCamera.allowHDR && this.occlusionSource == AmbientOcclusion.OcclusionSource.GBuffer;
			}
		}

		// Token: 0x170001CB RID: 459
		// (get) Token: 0x060017BD RID: 6077 RVA: 0x00064D8D File Offset: 0x0006318D
		public bool isGBufferAvailable
		{
			get
			{
				return this.targetCamera.actualRenderingPath == RenderingPath.DeferredShading;
			}
		}

		// Token: 0x170001CC RID: 460
		// (get) Token: 0x060017BE RID: 6078 RVA: 0x00064D9D File Offset: 0x0006319D
		private float intensity
		{
			get
			{
				return this.settings.intensity;
			}
		}

		// Token: 0x170001CD RID: 461
		// (get) Token: 0x060017BF RID: 6079 RVA: 0x00064DAA File Offset: 0x000631AA
		private float radius
		{
			get
			{
				return Mathf.Max(this.settings.radius, 0.0001f);
			}
		}

		// Token: 0x170001CE RID: 462
		// (get) Token: 0x060017C0 RID: 6080 RVA: 0x00064DC1 File Offset: 0x000631C1
		private AmbientOcclusion.SampleCount sampleCount
		{
			get
			{
				return this.settings.sampleCount;
			}
		}

		// Token: 0x170001CF RID: 463
		// (get) Token: 0x060017C1 RID: 6081 RVA: 0x00064DD0 File Offset: 0x000631D0
		private int sampleCountValue
		{
			get
			{
				switch (this.settings.sampleCount)
				{
				case AmbientOcclusion.SampleCount.Lowest:
					return 3;
				case AmbientOcclusion.SampleCount.Low:
					return 6;
				case AmbientOcclusion.SampleCount.Medium:
					return 12;
				case AmbientOcclusion.SampleCount.High:
					return 20;
				default:
					return Mathf.Clamp(this.settings.sampleCountValue, 1, 256);
				}
			}
		}

		// Token: 0x170001D0 RID: 464
		// (get) Token: 0x060017C2 RID: 6082 RVA: 0x00064E24 File Offset: 0x00063224
		private AmbientOcclusion.OcclusionSource occlusionSource
		{
			get
			{
				if (this.settings.occlusionSource == AmbientOcclusion.OcclusionSource.GBuffer && !this.isGBufferAvailable)
				{
					return AmbientOcclusion.OcclusionSource.DepthNormalsTexture;
				}
				return this.settings.occlusionSource;
			}
		}

		// Token: 0x170001D1 RID: 465
		// (get) Token: 0x060017C3 RID: 6083 RVA: 0x00064E4F File Offset: 0x0006324F
		private bool downsampling
		{
			get
			{
				return this.settings.downsampling;
			}
		}

		// Token: 0x170001D2 RID: 466
		// (get) Token: 0x060017C4 RID: 6084 RVA: 0x00064E5C File Offset: 0x0006325C
		private bool ambientOnly
		{
			get
			{
				return this.settings.ambientOnly && !this.settings.debug && this.isAmbientOnlySupported;
			}
		}

		// Token: 0x170001D3 RID: 467
		// (get) Token: 0x060017C5 RID: 6085 RVA: 0x00064E87 File Offset: 0x00063287
		private RenderTextureFormat aoTextureFormat
		{
			get
			{
				if (SystemInfo.SupportsRenderTextureFormat(RenderTextureFormat.R8))
				{
					return RenderTextureFormat.R8;
				}
				return RenderTextureFormat.Default;
			}
		}

		// Token: 0x170001D4 RID: 468
		// (get) Token: 0x060017C6 RID: 6086 RVA: 0x00064E99 File Offset: 0x00063299
		private Shader aoShader
		{
			get
			{
				if (this._aoShader == null)
				{
					this._aoShader = Shader.Find("Hidden/Image Effects/Cinematic/AmbientOcclusion");
				}
				return this._aoShader;
			}
		}

		// Token: 0x170001D5 RID: 469
		// (get) Token: 0x060017C7 RID: 6087 RVA: 0x00064EC2 File Offset: 0x000632C2
		private Material aoMaterial
		{
			get
			{
				if (this._aoMaterial == null)
				{
					this._aoMaterial = ImageEffectHelper.CheckShaderAndCreateMaterial(this.aoShader);
				}
				return this._aoMaterial;
			}
		}

		// Token: 0x170001D6 RID: 470
		// (get) Token: 0x060017C8 RID: 6088 RVA: 0x00064EEC File Offset: 0x000632EC
		private CommandBuffer aoCommands
		{
			get
			{
				if (this._aoCommands == null)
				{
					this._aoCommands = new CommandBuffer();
					this._aoCommands.name = "AmbientOcclusion";
				}
				return this._aoCommands;
			}
		}

		// Token: 0x170001D7 RID: 471
		// (get) Token: 0x060017C9 RID: 6089 RVA: 0x00064F1A File Offset: 0x0006331A
		private Camera targetCamera
		{
			get
			{
				return base.GetComponent<Camera>();
			}
		}

		// Token: 0x170001D8 RID: 472
		// (get) Token: 0x060017CA RID: 6090 RVA: 0x00064F22 File Offset: 0x00063322
		// (set) Token: 0x060017CB RID: 6091 RVA: 0x00064F2A File Offset: 0x0006332A
		private AmbientOcclusion.PropertyObserver propertyObserver { get; set; }

		// Token: 0x170001D9 RID: 473
		// (get) Token: 0x060017CC RID: 6092 RVA: 0x00064F33 File Offset: 0x00063333
		private Mesh quadMesh
		{
			get
			{
				return this._quadMesh;
			}
		}

		// Token: 0x060017CD RID: 6093 RVA: 0x00064F3C File Offset: 0x0006333C
		private void BuildAOCommands()
		{
			CommandBuffer aoCommands = this.aoCommands;
			int pixelWidth = this.targetCamera.pixelWidth;
			int pixelHeight = this.targetCamera.pixelHeight;
			int num = (!this.downsampling) ? 1 : 2;
			RenderTextureFormat aoTextureFormat = this.aoTextureFormat;
			RenderTextureReadWrite readWrite = RenderTextureReadWrite.Linear;
			FilterMode filter = FilterMode.Bilinear;
			Material aoMaterial = this.aoMaterial;
			int nameID = Shader.PropertyToID("_OcclusionTexture");
			aoCommands.GetTemporaryRT(nameID, pixelWidth / num, pixelHeight / num, 0, filter, aoTextureFormat, readWrite);
			aoCommands.Blit(null, nameID, aoMaterial, 2);
			int nameID2 = Shader.PropertyToID("_OcclusionBlurTexture");
			aoCommands.GetTemporaryRT(nameID2, pixelWidth, pixelHeight, 0, filter, aoTextureFormat, readWrite);
			aoCommands.SetGlobalVector("_BlurVector", Vector2.right * 2f);
			aoCommands.Blit(nameID, nameID2, aoMaterial, 4);
			aoCommands.ReleaseTemporaryRT(nameID);
			aoCommands.GetTemporaryRT(nameID, pixelWidth, pixelHeight, 0, filter, aoTextureFormat, readWrite);
			aoCommands.SetGlobalVector("_BlurVector", Vector2.up * 2f * (float)num);
			aoCommands.Blit(nameID2, nameID, aoMaterial, 4);
			aoCommands.ReleaseTemporaryRT(nameID2);
			aoCommands.GetTemporaryRT(nameID2, pixelWidth, pixelHeight, 0, filter, aoTextureFormat, readWrite);
			aoCommands.SetGlobalVector("_BlurVector", Vector2.right * (float)num);
			aoCommands.Blit(nameID, nameID2, aoMaterial, 6);
			aoCommands.ReleaseTemporaryRT(nameID);
			aoCommands.GetTemporaryRT(nameID, pixelWidth, pixelHeight, 0, filter, aoTextureFormat, readWrite);
			aoCommands.SetGlobalVector("_BlurVector", Vector2.up * (float)num);
			aoCommands.Blit(nameID2, nameID, aoMaterial, 6);
			aoCommands.ReleaseTemporaryRT(nameID2);
			RenderTargetIdentifier[] colors = new RenderTargetIdentifier[]
			{
				BuiltinRenderTextureType.GBuffer0,
				BuiltinRenderTextureType.CameraTarget
			};
			aoCommands.SetRenderTarget(colors, BuiltinRenderTextureType.CameraTarget);
			aoCommands.SetGlobalTexture("_OcclusionTexture", nameID);
			aoCommands.DrawMesh(this.quadMesh, Matrix4x4.identity, aoMaterial, 0, 8);
			aoCommands.ReleaseTemporaryRT(nameID);
		}

		// Token: 0x060017CE RID: 6094 RVA: 0x00065178 File Offset: 0x00063578
		private void ExecuteAOPass(RenderTexture source, RenderTexture destination)
		{
			int width = source.width;
			int height = source.height;
			int num = (!this.downsampling) ? 1 : 2;
			RenderTextureFormat aoTextureFormat = this.aoTextureFormat;
			RenderTextureReadWrite readWrite = RenderTextureReadWrite.Linear;
			bool flag = this.settings.occlusionSource == AmbientOcclusion.OcclusionSource.GBuffer;
			Material aoMaterial = this.aoMaterial;
			RenderTexture temporary = RenderTexture.GetTemporary(width / num, height / num, 0, aoTextureFormat, readWrite);
			Graphics.Blit(null, temporary, aoMaterial, (int)this.occlusionSource);
			RenderTexture temporary2 = RenderTexture.GetTemporary(width, height, 0, aoTextureFormat, readWrite);
			aoMaterial.SetVector("_BlurVector", Vector2.right * 2f);
			Graphics.Blit(temporary, temporary2, aoMaterial, (!flag) ? 3 : 4);
			RenderTexture.ReleaseTemporary(temporary);
			temporary = RenderTexture.GetTemporary(width, height, 0, aoTextureFormat, readWrite);
			aoMaterial.SetVector("_BlurVector", Vector2.up * 2f * (float)num);
			Graphics.Blit(temporary2, temporary, aoMaterial, (!flag) ? 3 : 4);
			RenderTexture.ReleaseTemporary(temporary2);
			temporary2 = RenderTexture.GetTemporary(width, height, 0, aoTextureFormat, readWrite);
			aoMaterial.SetVector("_BlurVector", Vector2.right * (float)num);
			Graphics.Blit(temporary, temporary2, aoMaterial, (!flag) ? 5 : 6);
			RenderTexture.ReleaseTemporary(temporary);
			temporary = RenderTexture.GetTemporary(width, height, 0, aoTextureFormat, readWrite);
			aoMaterial.SetVector("_BlurVector", Vector2.up * (float)num);
			Graphics.Blit(temporary2, temporary, aoMaterial, (!flag) ? 5 : 6);
			RenderTexture.ReleaseTemporary(temporary2);
			aoMaterial.SetTexture("_OcclusionTexture", temporary);
			if (!this.settings.debug)
			{
				Graphics.Blit(source, destination, aoMaterial, 7);
			}
			else
			{
				Graphics.Blit(source, destination, aoMaterial, 9);
			}
			RenderTexture.ReleaseTemporary(temporary);
		}

		// Token: 0x060017CF RID: 6095 RVA: 0x00065360 File Offset: 0x00063760
		private void UpdateMaterialProperties()
		{
			Material aoMaterial = this.aoMaterial;
			aoMaterial.SetFloat("_Intensity", this.intensity);
			aoMaterial.SetFloat("_Radius", this.radius);
			aoMaterial.SetFloat("_TargetScale", (!this.downsampling) ? 1f : 0.5f);
			aoMaterial.SetInt("_SampleCount", this.sampleCountValue);
		}

		// Token: 0x060017D0 RID: 6096 RVA: 0x000653CC File Offset: 0x000637CC
		private void OnEnable()
		{
			if (!ImageEffectHelper.IsSupported(this.aoShader, true, false, this))
			{
				base.enabled = false;
				return;
			}
			if (this.ambientOnly)
			{
				this.targetCamera.AddCommandBuffer(CameraEvent.BeforeReflections, this.aoCommands);
			}
			if (this.occlusionSource == AmbientOcclusion.OcclusionSource.DepthTexture)
			{
				this.targetCamera.depthTextureMode |= DepthTextureMode.Depth;
			}
			if (this.occlusionSource != AmbientOcclusion.OcclusionSource.GBuffer)
			{
				this.targetCamera.depthTextureMode |= DepthTextureMode.DepthNormals;
			}
		}

		// Token: 0x060017D1 RID: 6097 RVA: 0x00065450 File Offset: 0x00063850
		private void OnDisable()
		{
			if (this._aoMaterial != null)
			{
				UnityEngine.Object.DestroyImmediate(this._aoMaterial);
			}
			this._aoMaterial = null;
			if (this._aoCommands != null)
			{
				this.targetCamera.RemoveCommandBuffer(CameraEvent.BeforeReflections, this._aoCommands);
			}
			this._aoCommands = null;
		}

		// Token: 0x060017D2 RID: 6098 RVA: 0x000654A8 File Offset: 0x000638A8
		private void Update()
		{
			if (this.propertyObserver.CheckNeedsReset(this.settings, this.targetCamera))
			{
				this.OnDisable();
				this.OnEnable();
				if (this.ambientOnly)
				{
					this.aoCommands.Clear();
					this.BuildAOCommands();
				}
				this.propertyObserver.Update(this.settings, this.targetCamera);
			}
			if (this.ambientOnly)
			{
				this.UpdateMaterialProperties();
			}
		}

		// Token: 0x060017D3 RID: 6099 RVA: 0x00065527 File Offset: 0x00063927
		[ImageEffectOpaque]
		private void OnRenderImage(RenderTexture source, RenderTexture destination)
		{
			if (this.ambientOnly)
			{
				Graphics.Blit(source, destination);
			}
			else
			{
				this.UpdateMaterialProperties();
				this.ExecuteAOPass(source, destination);
			}
		}

		// Token: 0x04000CFC RID: 3324
		[SerializeField]
		public AmbientOcclusion.Settings settings = AmbientOcclusion.Settings.defaultSettings;

		// Token: 0x04000CFD RID: 3325
		[SerializeField]
		private Shader _aoShader;

		// Token: 0x04000CFE RID: 3326
		private Material _aoMaterial;

		// Token: 0x04000CFF RID: 3327
		private CommandBuffer _aoCommands;

		// Token: 0x04000D01 RID: 3329
		[SerializeField]
		private Mesh _quadMesh;

		// Token: 0x0200045B RID: 1115
		private struct PropertyObserver
		{
			// Token: 0x060017D4 RID: 6100 RVA: 0x00065550 File Offset: 0x00063950
			public bool CheckNeedsReset(AmbientOcclusion.Settings setting, Camera camera)
			{
				return this._downsampling != setting.downsampling || this._occlusionSource != setting.occlusionSource || this._ambientOnly != setting.ambientOnly || this._debug != setting.debug || this._pixelWidth != camera.pixelWidth || this._pixelHeight != camera.pixelHeight;
			}

			// Token: 0x060017D5 RID: 6101 RVA: 0x000655C8 File Offset: 0x000639C8
			public void Update(AmbientOcclusion.Settings setting, Camera camera)
			{
				this._downsampling = setting.downsampling;
				this._occlusionSource = setting.occlusionSource;
				this._ambientOnly = setting.ambientOnly;
				this._debug = setting.debug;
				this._pixelWidth = camera.pixelWidth;
				this._pixelHeight = camera.pixelHeight;
			}

			// Token: 0x04000D02 RID: 3330
			private bool _downsampling;

			// Token: 0x04000D03 RID: 3331
			private AmbientOcclusion.OcclusionSource _occlusionSource;

			// Token: 0x04000D04 RID: 3332
			private bool _ambientOnly;

			// Token: 0x04000D05 RID: 3333
			private bool _debug;

			// Token: 0x04000D06 RID: 3334
			private int _pixelWidth;

			// Token: 0x04000D07 RID: 3335
			private int _pixelHeight;
		}

		// Token: 0x0200045C RID: 1116
		public enum SampleCount
		{
			// Token: 0x04000D09 RID: 3337
			Lowest,
			// Token: 0x04000D0A RID: 3338
			Low,
			// Token: 0x04000D0B RID: 3339
			Medium,
			// Token: 0x04000D0C RID: 3340
			High,
			// Token: 0x04000D0D RID: 3341
			Variable
		}

		// Token: 0x0200045D RID: 1117
		public enum OcclusionSource
		{
			// Token: 0x04000D0F RID: 3343
			DepthTexture,
			// Token: 0x04000D10 RID: 3344
			DepthNormalsTexture,
			// Token: 0x04000D11 RID: 3345
			GBuffer
		}

		// Token: 0x0200045E RID: 1118
		[Serializable]
		public class Settings
		{
			// Token: 0x170001DA RID: 474
			// (get) Token: 0x060017D7 RID: 6103 RVA: 0x00065628 File Offset: 0x00063A28
			public static AmbientOcclusion.Settings defaultSettings
			{
				get
				{
					return new AmbientOcclusion.Settings
					{
						intensity = 1f,
						radius = 0.3f,
						sampleCount = AmbientOcclusion.SampleCount.Medium,
						sampleCountValue = 24,
						downsampling = false,
						ambientOnly = false,
						occlusionSource = AmbientOcclusion.OcclusionSource.DepthNormalsTexture
					};
				}
			}

			// Token: 0x04000D12 RID: 3346
			[SerializeField]
			[Range(0f, 4f)]
			[Tooltip("Degree of darkness produced by the effect.")]
			public float intensity;

			// Token: 0x04000D13 RID: 3347
			[SerializeField]
			[Tooltip("Radius of sample points, which affects extent of darkened areas.")]
			public float radius;

			// Token: 0x04000D14 RID: 3348
			[SerializeField]
			[Tooltip("Number of sample points, which affects quality and performance.")]
			public AmbientOcclusion.SampleCount sampleCount;

			// Token: 0x04000D15 RID: 3349
			[SerializeField]
			[Tooltip("Determines the sample count when SampleCount.Variable is used.")]
			public int sampleCountValue;

			// Token: 0x04000D16 RID: 3350
			[SerializeField]
			[Tooltip("Halves the resolution of the effect to increase performance.")]
			public bool downsampling;

			// Token: 0x04000D17 RID: 3351
			[SerializeField]
			[Tooltip("If checked, the effect only affects ambient lighting.")]
			public bool ambientOnly;

			// Token: 0x04000D18 RID: 3352
			[SerializeField]
			[Tooltip("Source buffer on which the occlusion estimator is based.")]
			public AmbientOcclusion.OcclusionSource occlusionSource;

			// Token: 0x04000D19 RID: 3353
			[SerializeField]
			[Tooltip("Displays occlusion for debug purpose.")]
			public bool debug;
		}
	}
}
